#include "PhysicInterface.h"
#define VLD_FORCE_ENABLE
#include "vld.h"

CPhysicInterface::CPhysicInterface()
	:m_pDataProvider(NULL)
{
	
}


void CPhysicInterface::SetDataProvider(CDataProviderInterface *pDataProvider)
{
	m_pDataProvider = pDataProvider;
}


CSimplePhysic::CSimplePhysic()
{
	Weight.clear();
	Env.clear();
	GetPosition.clear();
}


CSimplePhysic::~CSimplePhysic()
{
	Weight.clear();
	Env.clear();
	GetPosition.clear();
}


//Get some points that use for computing the Interpolation
void CSimplePhysic::ReadPosFile(string filename)
{
	ifstream is;
	unsigned int i;
	is.open(filename.c_str());

	for (i = 0; i < 10; i++)
	{
		Vector3f Ve;
		is >> Ve.x;
		is >> Ve.y;
		is >> Ve.z;

		GetPosition.push_back(Ve);
	}
}



//Computing the Weight of a special point by the IDW(Inverse Distance Weighting)
void CSimplePhysic::ComputeWeightAtThisPos( Vector3f& pos )
{
	typedef std::vector<EnvironmentParameters>::size_type ENV_DATA_TYPE;
	std::vector<EnvironmentParameters>& Parameters = m_pDataProvider->GetEnvironmentParameters();
	float sum = 0.0f, value = 0.0f;
	unsigned int i;

	for (ENV_DATA_TYPE idx = 0; idx < Parameters.size(); ++idx)
	{
	EnvironmentParameters& para = Parameters[idx];
	Vector3f dir;
	dir = pos - para.Position;
	value = 1/dir.Magnitude();
	sum += value;
	Weight.push_back(value);
	}

	for (i = 0; i < Weight.size(); i++)
	{
		Weight.at(i) /= sum;
	}
}



//Get the Interpolation of a special point in Scene
EnvironmentParameters CSimplePhysic::ComputeEnvironmentParameterAtThisPos(Vector3f& pos)
{
	typedef std::vector<EnvironmentParameters>::size_type ENV_DATA_TYPE;
	std::vector<EnvironmentParameters>& Parameters = m_pDataProvider->GetEnvironmentParameters();
	EnvironmentParameters target;
	ComputeWeightAtThisPos(pos);

	for (ENV_DATA_TYPE idx = 0; idx < Parameters.size(); ++idx)
	{
		EnvironmentParameters& para = Parameters[idx];
		target.Position += para.Position * Weight.at(idx);
		target.WindDirection += para.WindDirection * Weight.at(idx);
		target.fTemperature += para.fTemperature * Weight.at(idx);
		target.fDensity += para.fDensity * Weight.at(idx);
		target.fHumidity += para.fHumidity * Weight.at(idx);
		target.fCrudeSalvation += para.fCrudeSalvation * Weight.at(idx);
		target.fSpeed += para.fSpeed * Weight.at(idx);
	}
	return target;
}



//Get the Interpolation of all special points in Scene
vector<EnvironmentParameters> CSimplePhysic::GetAllEnvInterpolateParameters()
{
	EnvironmentParameters Envir;
	vector<EnvironmentParameters> ReturnEnvParameters;
	ReturnEnvParameters.clear();
	ReadPosFile("Pos.txt");
	for (vector<Vector3f>::iterator iter = GetPosition.begin();
		iter != GetPosition.end(); iter++)
	{
		Envir = ComputeEnvironmentParameterAtThisPos(*iter);
		ReturnEnvParameters.push_back(Envir);
	}
	return ReturnEnvParameters;
}



vector<EnvironmentParameters> CSimplePhysic::GetAllEnvironmentParameters()
{
	return GetAllEnvironmentParameters();
}


EnvironmentParameters CSimplePhysic::GetEnvironmentParameterAtThisPos(Vector3f& pos)
{
	return ComputeEnvironmentParameterAtThisPos(pos);
}

